module OptimisationTypes
use HTypes
use strutils
implicit none

!type RealPtr
!   double precision, pointer :: Value => null()
!end type

! TDataSource
type TDataSource
   !double precision :: Weight
   double precision :: FProp
   double precision :: MProp
   integer :: ObjType
   double precision :: Weight
   double precision :: My ! Small residual offset
   integer :: PlusGroupCode
   
   ! Bootsrap source data
   double precision, pointer :: BootObs(:, :, :) => null()  ! Dimension Run, ,Year, Age
   integer :: BootType
   double precision :: Sigma
   character(len = 32) :: BootFile = "NA"! Boot file
end type TDataSource


type TDataSourceArray
   type(TDataSource), pointer :: Elm(:) => null() ![iDataSource]
end type TDataSourceArray;



! TInput -- The index input
type TIndexInput
   character(len = 256) :: StockTitle ! Stock title
   integer :: ProcessType       ! Process type
   integer :: SearchRoutine     ! Search routine (0=General 1=BFGS)
   integer :: ModelType         ! Population model type
   integer :: ISVPAControlType  ! Control type if ISVPA is choosen (Catch or Effort)
   integer :: PlusGroupMethod   ! Population plus group method
   integer :: FirstYear     ! First year in model
   integer :: LastYear      ! Last year in model
   integer :: LastCatchYear ! Last catch year in model
   integer :: FirstAge      ! First age in model
   integer :: LastAge       ! Last age in model
   integer :: FirstRefAge      ! First referenced age in model
   integer :: LastRefAge       ! Last referenced age in model
   integer :: NumMedianElms ! Number of median elements
!   double precision :: GammaShape    ! Gamma shape parameter
   integer :: NumStages   ! Number of bootstrap runs
   double precision :: SSBFracF   ! Fraction F before spawning
   double precision :: SSBFracM   ! Fraction M before spawning
   type(TDataSourceArray), pointer :: DataSources(:) => null()

   character(len = cFileNameLength) :: DataFiles(odFirst : odLast) ! Observed data files
   character(len = cFileNameLength) :: InParamFileName
   character(len = cFileNameLength) :: OutFiles(roFirst : roLast)  ! Run out files
end type TIndexInput


!-- TObservedData -- the Observed Data input matrix
type TObservedData
   character(len = cStockTitleLength) :: Title 
   character(len = cTechNameLength) :: TechName
   integer :: Variable  
   integer :: FirstYear
   integer :: NumYears
   integer :: FirstAge
   integer :: NumAges
   integer :: NumDig, NumDec
   integer :: NumPositiveUnweightedResiduals
   double precision, pointer :: Obs(:,:) => null()
   double precision, pointer :: ResU(:, :) => null()
   double precision, pointer :: ResW(:, :) => null()
   double precision, pointer :: ModVal(:, :) => null()
   double precision, pointer :: Phi(:, :) => null()
   double precision, pointer :: PhiWeight(:, :) => null()
   double precision, pointer :: PhiArray(:) => null()
   double precision, pointer :: ResArray(:) => null()
   double precision, pointer :: CblFac(:, :) => null()
   double precision, pointer :: CblPow(:, :) => null()
   double precision, pointer :: NFromDS(:, :) => null()
end type TObservedData


type TObservedDataArray
   type(TObservedData), pointer :: Elm(:) => null()
end type TObservedDataArray




type TPopModel
   double precision, pointer :: Nay(:, :) => null()
   double precision, pointer :: Fay(:, :) => null()
   double precision, pointer :: May(:, :) => null()
   double precision, pointer :: InternalCatchISVPA(:, :) => null()
   double precision, pointer :: StockSummary (:, :) => null()
end type TPopModel


!--TParamElm--------------
type TParamElm
   double precision, pointer :: Value => null()
   !double precision :: Value
   integer :: Cat, Flag, Index, Year, Age
   character(len = c_ParamElmDescrLen) :: Descr
   type(TParamElm), pointer :: NextYear => null()
   type(TParamElm), pointer :: NextAge => null()
end type TParamElm


!--TParamCube-----------------
type TParamCube
   type(TParamElm), pointer :: Elm(:,:,:) => null() ![Fleet, Year, Age]
end type TParamCube;


type TOptimiseLocation
   integer :: Stage = 0
   integer :: Iter 
   double precision :: Delta, ObjFunc
   logical :: Improved
end type TOptimiseLocation


type TOptimisation
   character(len = cFileNameLength) :: ProjectDir
   character(len = cFileNameLength) :: RunName
   type(TIndexInput), pointer :: IndexInput => null()
   type(TObservedDataArray), pointer :: ObservedData(:) => null()
   type(TPopModel), pointer :: PopModel => null()
   type(TParamCube), pointer :: ParamCubes(:) => null()
   type(TParamElm), pointer :: pactive(:) => null()
   integer, pointer :: iseq(:)
   double precision, pointer :: seq(:)
   type(TOptimiseLocation), pointer :: Loc => null()
   double precision :: seed
   logical :: DumpTuningDetails = .false.
   logical :: DumpCalculationDetails = .false.
   logical :: DebugMode = .false.
   character(len = 20) :: RunId
   character(len = 256) :: ErrorStr
   character(len = 256) :: RunErrorStr
   character(len = 256) :: CurrentInputFile
   integer :: CurrentInputLine
   double precision :: FileVersion
end type TOptimisation

end module OptimisationTypes

